import {ChangeDetectorRef, Component, forwardRef, Inject, Input, OnInit} from '@angular/core';
import {SysRegionTreeNodeService} from '../service/sys-region-tree-node.service';
import {RegionLevel, SysRegion} from '../entity/sys-region';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';


@Component({
    selector: 'sys-region-select',
    templateUrl: './sys-region-select.component.html',
    styleUrls: ['./sys-region-select.component.less'],
    providers: [
        {
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => SysRegionSelectComponent),
            multi: true
        }
    ]
})
export class SysRegionSelectComponent implements OnInit, ControlValueAccessor {
    /**
     * 在最上层的过滤条件
     * 默认为：100000
     * 例如省级的上一层为国家：100000
     */
    @Input()
    aboveTopLevelCode: string;

    @Input()
    valueChange: (value: string | string[] | object) => any;
    @Input()
    valueType: 'string' | 'array' | 'object' = 'array';

    @Input()
    showProvince = true;
    province = '';
    provinceValues: SysRegion[] = [];


    @Input()
    showCity = true;
    city = '';
    cityValues: SysRegion[] = [];

    @Input()
    showDistrict = true;
    district = '';
    districtValues: SysRegion[] = [];


    @Input()
    showStreet = true;
    street = '';
    streetValues: SysRegion[] = [];

    @Input()
    showCun = true;
    cun = '';
    cunValues: SysRegion[] = [];

    @Input()
    showGroup = true;
    group = '';
    groupValues: SysRegion[] = [];

    @Input()
    eachWidth = '50%';
    changeFn = undefined;
    disabled = false;

    constructor(protected sysRegionService: SysRegionTreeNodeService,
                @Inject(ChangeDetectorRef) public readonly cd: ChangeDetectorRef) {
    }

    _value;

    get value() {
        return this._value;
    }

    set value(value: any) {
        this._value = value;
        if (this.changeFn) {
            this.changeFn(value);
        }
    }

    ngOnInit(): void {
        let topLevel: RegionLevel = 'COUNTRY';
        if (this.showProvince) {
            topLevel = 'COUNTRY';
        } else if (this.showCity) {
            topLevel = 'PROVINCE';
        } else if (this.showDistrict) {
            topLevel = 'CITY';
        } else if (this.showStreet) {
            topLevel = 'DISTRICT';
        } else if (this.showCun) {
            topLevel = 'STREET';
        } else if (this.showGroup) {
            topLevel = 'GROUP';
        }
        if (topLevel === 'COUNTRY' && !this.aboveTopLevelCode) {
            this.aboveTopLevelCode = '100000';
        }
        if (!this.valueType) {
            this.valueType = 'array';
        }
        this.changeSelect(this.aboveTopLevelCode, topLevel);
    }

    changeSelect(code: string, level: RegionLevel) {

        let doSearch = false;

        if (level === 'COUNTRY') {
            this.province = undefined;
            this.provinceValues = [];

            this.city = undefined;
            this.cityValues = [];

            this.district = undefined;
            this.districtValues = [];

            this.street = undefined;
            this.streetValues = [];

            this.cun = undefined;
            this.cunValues = [];

            this.group = undefined;
            this.groupValues = [];

            if (this.showProvince) {
                doSearch = true;
            }
        }

        if (level === 'PROVINCE') {
            this.city = undefined;
            this.cityValues = [];

            this.district = undefined;
            this.districtValues = [];

            this.street = undefined;
            this.streetValues = [];

            this.cun = undefined;
            this.cunValues = [];

            this.group = undefined;
            this.groupValues = [];

            if (this.showCity) {
                doSearch = true;
            }
        }

        if (level === 'CITY') {
            this.district = undefined;
            this.districtValues = [];

            this.street = undefined;
            this.streetValues = [];

            this.cun = undefined;
            this.cunValues = [];

            this.group = undefined;
            this.groupValues = [];

            if (this.showDistrict) {
                doSearch = true;
            }
        }

        if (level === 'DISTRICT') {
            this.street = undefined;
            this.streetValues = [];

            this.cun = undefined;
            this.cunValues = [];

            this.group = undefined;
            this.groupValues = [];

            if (this.showStreet) {
                doSearch = true;
            }
        }

        if (level === 'STREET') {

            this.cun = undefined;
            this.cunValues = [];

            this.group = undefined;
            this.groupValues = [];

            if (this.showCun) {
                doSearch = true;
            }
        }

        if (level === 'STREET') {

            this.group = undefined;
            this.groupValues = [];

            if (this.showGroup) {
                doSearch = true;
            }
        }

        if (!doSearch || !code) {
            return;
        }
        this.sysRegionService.getChildrenNoSpatial(code).subscribe(returnForm => {
            if (returnForm && returnForm.success) {
                returnForm.message.forEach(value => {
                    if (value.level === 'GROUP') {
                        this.groupValues.push(value);
                    } else if (value.level === 'CUN') {
                        this.cunValues.push(value);
                    } else if (value.level === 'STREET') {
                        this.streetValues.push(value);
                    } else if (value.level === 'DISTRICT') {
                        this.districtValues.push(value);
                    } else if (value.level === 'CITY') {
                        this.cityValues.push(value);
                    } else if (value.level === 'PROVINCE') {
                        this.provinceValues.push(value);
                    }
                });
                this.cd.detectChanges();
            }
        });
    }

    updateValue() {
        const arr = [];
        if (this.showProvince) {
            arr.push(this.province);
        }
        if (this.showCity) {
            arr.push(this.city);
        }
        if (this.showDistrict) {
            arr.push(this.district);
        }
        if (this.showStreet) {
            arr.push(this.street);
        }
        if (this.showCun) {
            arr.push(this.cun);
        }
        if (this.showGroup) {
            arr.push(this.group);
        }

        if (this.valueType === 'string') {
            if (this.valueChange) {
                this.valueChange(arr.join(','));
            }
            this.value = arr.join(',');
        } else if (this.valueType === 'array') {
            if (this.valueChange) {
                this.valueChange(arr);
            }
            this.value = arr;
        } else if (this.valueType === 'object') {
            const obj = {};
            if (this.showProvince) {
                obj['province'] = this.province;
            }
            if (this.showCity) {
                obj['city'] = this.city;
            }
            if (this.showDistrict) {
                obj['district'] = this.district;
            }
            if (this.showStreet) {
                obj['street'] = this.street;
            }
            if (this.showCun) {
                obj['cun'] = this.cun;
            }
            if (this.showGroup) {
                obj['group'] = this.group;
            }
            if (this.valueChange) {
                this.valueChange(obj);
            }
            this.value = obj;
        }

    }

    provinceChange() {
        this.changeSelect(this.province, 'PROVINCE');
        this.updateValue();
    }

    cityChange() {
        this.changeSelect(this.city, 'CITY');
        this.updateValue();
    }

    districtChange() {
        this.changeSelect(this.district, 'DISTRICT');
        this.updateValue();
    }

    streetChange() {
        this.changeSelect(this.street, 'STREET');
        this.updateValue();
    }

    cunChange() {
        this.changeSelect(this.cun, 'CUN');
        this.updateValue();
    }

    groupChange() {
        this.updateValue();
    }

    registerOnChange(fn: any): void {
        this.changeFn = fn;
    }

    registerOnTouched(fn: any): void {
    }

    setDisabledState(isDisabled: boolean): void {
        this.disabled = isDisabled;
    }

    writeValue(_value: any): void {
        if (!_value) {
            return;
        }
        if (this.valueType === 'string' || this.valueType === 'array') {
            let arr = [];
            if (typeof _value === 'string') {
                arr = _value.split(',');
            } else if (_value instanceof Array) {
                arr = _value;
            }

            let index = 0;

            if (this.showProvince && arr.length > index) {
                this.province = arr[index++];
                this.changeSelect(this.province, 'PROVINCE');
            }
            if (this.showCity && arr.length > index) {
                this.city = arr[index++];
                this.changeSelect(this.city, 'CITY');
            }
            if (this.showDistrict && arr.length > index) {
                this.district = arr[index++];
                this.changeSelect(this.district, 'DISTRICT');
            }
            if (this.showStreet && arr.length > index) {
                this.street = arr[index++];
                this.changeSelect(this.street, 'STREET');
            }

            if (this.showCun && arr.length > index) {
                this.cun = arr[index++];
                this.changeSelect(this.cun, 'CUN');
            }

            if (this.showGroup && arr.length > index) {
                this.group = arr[index++];
                this.changeSelect(this.group, 'GROUP');
            }

            this.updateValue();
        } else if (this.valueType === 'object' && typeof _value === 'object') {

            if (this.showProvince && _value['province']) {
                this.province = _value['province'];
                this.changeSelect(this.province, 'PROVINCE');
            }
            if (this.showCity && _value['city']) {
                this.city = _value['city'];
                this.changeSelect(this.city, 'CITY');
            }
            if (this.showDistrict && _value['district']) {
                this.district = _value['district'];
                this.changeSelect(this.district, 'DISTRICT');
            }
            if (this.showStreet && _value['street']) {
                this.street = _value['street'];
                this.changeSelect(this.street, 'STREET');
            }

            if (this.showCun && _value['cun']) {
                this.cun = _value['cun'];
                this.changeSelect(this.cun, 'CUN');
            }

            if (this.showGroup && _value['group']) {
                this.group = _value['group'];
                this.changeSelect(this.group, 'GROUP');
            }


            this.updateValue();
        }
    }
}
